from django.contrib import admin
# Register your models here.
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.contrib.admin.models import LogEntry
from django.core.cache import cache
from django.db.models import Max, Q
from import_export.admin import ImportExportModelAdmin

from pms import models
from pms import resource
from pms.utils import RabbitUtil
from yl_pms.utils import err_msg, set_user


@admin.register(models.MainProject)
class MainProjectAdmin(admin.ModelAdmin):
    """项目信息"""
    list_display = ('id', 'pc', 'ps', 'pn', 'es', 'port', 'is_enable', 'env_run', 'remarks')
    list_editable = ('env_run', )
    fields = ('id', 'pc', 'ps', 'pn', 'es', 'port', 'is_enable', 'env_run', 'remarks')
    list_display_links = ('id', 'pc', 'ps', 'pn', 'es', 'port', 'is_enable')
    ordering = ('id',)
    empty_value_display = '-auto-'
    readonly_fields = ['id']
    search_fields = ['ps', 'pn']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        super(MainProjectAdmin, self).save_model(request, obj, form, change)


@admin.register(models.BaseProject)
class BaseProjectAdmin(admin.ModelAdmin):
    """项目信息"""
    list_display = ('id', 'code', 'name', 'remarks')
    list_editable = ('code', 'name', 'remarks')
    fields = ('id', 'code', 'name', 'remarks')
    ordering = ('id',)
    empty_value_display = '-auto-'
    search_fields = ['id', 'code', 'name']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        set_user(request, obj)
        super(BaseProjectAdmin, self).save_model(request, obj, form, change)

    def has_delete_permission(self, request, obj=None):
        # 禁用删除按钮
        return True

    # def get_actions(self, request):
    #     # 在actions中去掉 删除 操作
    #     actions = super(BaseProjectAdmin, self).get_actions(request)
    #     if 'delete_selected' in actions:
    #         del actions['delete_selected']
    #     return actions


@admin.register(models.BaseTargetType)
class BaseTargetTypeAdmin(ImportExportModelAdmin):
    """类型信息"""
    resource_class = resource.BaseTargetTypeResource
    list_display = ('id', 'tag', 'name', 'remarks')
    list_editable = ('tag', 'name', 'remarks')
    fields = ('id', 'tag', 'name', 'remarks')
    ordering = ('id',)
    empty_value_display = '-auto-'
    search_fields = ['id', 'tag', 'name']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        set_user(request, obj)
        exist_obj = models.FakeVal.objects.filter(type_id=obj.id)
        if len(exist_obj) == 0:
            models.FakeVal.objects.create(type_id=obj.id, type_code=obj.tag, type_name=obj.name)
        super(BaseTargetTypeAdmin, self).save_model(request, obj, form, change)

    def get_queryset(self, request):
        raw_obj = models.BaseTargetType.objects.values()
        sync_obj = models.FakeVal.objects.values()
        if len(raw_obj) != len(sync_obj):
            raw_ids = []
            dict_obj = {}
            sync_ids = []
            for o in raw_obj:
                type_id = o['id']
                raw_ids.append(type_id)
                dict_obj[type_id] = o
            for o in sync_obj:
                type_id = o['type_id']
                sync_ids.append(type_id)
            for raw_id in raw_ids:
                if raw_id not in sync_ids:
                    models.FakeVal.objects.filter(type_id=raw_id).delete()
            no_ids = set(raw_ids) ^ set(sync_ids)
            for type_id in no_ids:
                o = dict_obj[type_id]
                models.FakeVal.objects.create(type_id=type_id, type_code=o['tag'], type_name=o['name'])
        return super(BaseTargetTypeAdmin, self).get_queryset(request)

    def delete_queryset(self, request, queryset):
        os = queryset.values()
        for obj in os:
            type_id = obj['id']
            models.FakeVal.objects.filter(type_id=type_id).delete()
        super(BaseTargetTypeAdmin, self).delete_queryset(request, queryset)


@admin.register(models.SettingsDataQuota)
class SettingsDataQuotaAdmin(ImportExportModelAdmin):
    """指标信息"""
    resource_class = resource.SettingsDataQuotaResource
    list_display = ('id', 'target_type', 'code', 'name', 'unit', 'display', 'remarks')
    list_editable = ('target_type', 'code', 'name', 'unit', 'display', 'remarks')
    fields = ('target_type', 'code', 'name', 'unit', 'display', 'remarks')
    ordering = ('target_type', 'code',)
    empty_value_display = '-auto-'
    # raw_id_fields = ('target_type',)
    search_fields = ['name']
    list_filter = ('target_type__id',)
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        set_user(request, obj)
        super(SettingsDataQuotaAdmin, self).save_model(request, obj, form, change)


@admin.register(models.WarnBase)
class WarnBaseAdmin(admin.ModelAdmin):
    """预警等级信息"""
    list_display = ('id', 'project', 'name', 'remarks')
    list_editable = ('project', 'name', 'remarks')
    fields = ('id', 'project', 'name', 'remarks')
    ordering = ('id',)
    empty_value_display = '-auto-'
    search_fields = ['name']
    list_filter = ('project',)
    readonly_fields = ['id']
    list_per_page = 20


@admin.register(models.BaseTargetSiteGroup)
class BaseTargetSiteGroupAdmin(ImportExportModelAdmin):
    """位置分区信息"""
    resource_class = resource.BaseTargetSiteGroupResource
    list_display = ('id', 'project', 'name')
    list_editable = ('project', 'name',)
    fields = ('id', 'project', 'name')
    ordering = ('id',)
    empty_value_display = '-auto-'
    search_fields = ['name']
    list_filter = ('project',)
    readonly_fields = ['id']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        res = models.BaseTargetSiteGroup.objects.filter(name=obj.name)
        if len(res) != 0:
            msg = '【分区名称】已存在'
            err_msg(request, msg)
        set_user(request, obj)
        super(BaseTargetSiteGroupAdmin, self).save_model(request, obj, form, change)

    # def has_delete_permission(self, request, obj=None):
    #     # 禁用删除按钮
    #     return False
    #
    # def get_actions(self, request):
    #     # 在actions中去掉 删除 操作
    #     actions = super(BaseTargetSiteGroupAdmin, self).get_actions(request)
    #     if 'delete_selected' in actions:
    #         del actions['delete_selected']
    #     return actions


@admin.register(models.BaseTargetSite)
class BaseTargetSiteAdmin(ImportExportModelAdmin):
    """位置信息"""
    resource_class = resource.BaseTargetSiteResource
    list_display = ('id', 'name', 'project', 'group', 'order_no')
    list_editable = ('name', 'project', 'group')
    fields = ('id', 'name', 'project', 'group', 'order_no')
    # raw_id_fields = ('project',)
    ordering = ('group', 'order_no',)
    empty_value_display = '-auto-'
    search_fields = ['id', 'name']
    readonly_fields = ['id', 'order_no']
    list_filter = ('project', 'group',)
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        if obj.id is None:
            res = models.BaseTargetSite.objects.filter(name=obj.name)
            if len(res) != 0:
                msg = '【位置名称】已存在'
                err_msg(request, msg)
            if obj.order_no is None:
                order_max = models.BaseTargetSite.objects.filter(
                    group__id=obj.group_id).aggregate(Max('order_no'))['order_no__max']
                if order_max is None:
                    obj.order_no = 1
                else:
                    obj.order_no = order_max + 1
        else:
            res = models.BaseTargetSite.objects.filter(name=obj.name).exclude(id=obj.id)
            if len(res) != 0:
                msg = '【位置名称】已存在'
                err_msg(request, msg)
        set_user(request, obj)
        super(BaseTargetSiteAdmin, self).save_model(request, obj, form, change)


class SettingsThInline(admin.TabularInline):
    model = models.SettingsThreshold
    extra = 0
    verbose_name = '阈值信息'
    verbose_name_plural = verbose_name
    fields = ('target', 'quota', 'level', 'lower', 'upper', 'absolute')
    raw_id_fields = ('quota',)


@admin.register(models.BaseTarget)
class BaseTargetAdmin(ImportExportModelAdmin):
    """测点信息"""
    # 对接资源类
    resource_class = resource.BaseTargetResource
    list_display = ('id', 'project', 'type', 'site', 'sta', 'serial_number', 'code', 'ths', 'demodulator', 'channel',
                    'initial', 'ratio')
    list_editable = ('project', 'type', 'site', 'serial_number', 'code', 'demodulator', 'channel', 'initial',
                     'ratio')
    fields = ('id', 'project', 'type', 'site', 'status', 'serial_number', 'code', 'demodulator', 'channel', 'initial',
              'ratio')
    list_filter = ('project', 'type', 'site', 'status')
    list_display_links = ('id', 'sta', 'ths')
    empty_value_display = '-auto-'
    search_fields = ['id', 'serial_number', 'code']
    ordering = ('project', 'serial_number')
    # raw_id_fields = ('type',)
    readonly_fields = ['id']
    list_per_page = 20
    inlines = [SettingsThInline]

    def ths(self, obj):
        return '查看详情'

    ths.short_description = '阈值信息'

    def save_model(self, request, obj, form, change):
        if obj.type_id == 1 and obj.ratio == 0:
            msg = '【转换系数】不能填0'
            err_msg(request, msg)
        if obj.id is None:
            res1 = models.BaseTarget.objects.filter(project_id=obj.project, serial_number=obj.serial_number)
            res2 = models.BaseTarget.objects.filter(project_id=obj.project, code=obj.code)
            res3 = models.BaseTarget.objects.filter(
                project_id=obj.project, demodulator=obj.demodulator, channel=obj.channel)
            if len(res1) != 0:
                msg = '【通讯编号】已存在'
                err_msg(request, msg)
            elif len(res2) != 0:
                msg = '【测点编号】已存在'
                err_msg(request, msg)
            elif len(res3) != 0:
                msg = '【解调仪编号-通道号】已存在'
                err_msg(request, msg)
            else:
                obj.name = obj.code
                obj.frequency = -1
                obj.order_no = obj.serial_number
        else:
            # 过滤不等于，两种写法【~Q()】【exclude()】，第一种写法需要写在第一个参数位置
            res1 = models.BaseTarget.objects.filter(
                ~Q(id=obj.id), project_id=obj.project, serial_number=obj.serial_number)
            res2 = models.BaseTarget.objects.filter(project_id=obj.project, code=obj.code).exclude(id=obj.id)
            res3 = models.BaseTarget.objects.filter(
                project_id=obj.project, demodulator=obj.demodulator, channel=obj.channel).exclude(id=obj.id)
            if len(res1) != 0:
                msg = '【通讯编号】已存在'
                err_msg(request, msg)
            elif len(res2) != 0:
                msg = '【测点编号】已存在'
                err_msg(request, msg)
            elif len(res3) != 0:
                msg = '【解调仪编号-通道号】已存在'
                err_msg(request, msg)
        set_user(request, obj)
        exist_obj = models.FakeTgt.objects.filter(pid=obj.project_id, sc=obj.serial_number)
        if len(exist_obj) == 0:
            models.FakeTgt.objects.create(pid=obj.project_id, type_id=obj.type_id, sc=obj.serial_number)
        super(BaseTargetAdmin, self).save_model(request, obj, form, change)

    def get_queryset(self, request):
        raw_obj = models.BaseTarget.objects.values()
        sync_obj = models.FakeTgt.objects.values()
        if len(raw_obj) != len(sync_obj):
            raw_pts = []
            sync_pts = []
            for o in raw_obj:
                pid = o['project_id']
                type_id = o['type_id']
                sc = o['serial_number']
                raw_pts.append('{}_{}_{}'.format(pid, type_id, sc))
            for o in sync_obj:
                pid = o['pid']
                type_id = o['type_id']
                sc = o['sc']
                sync_pts.append('{}_{}_{}'.format(pid, type_id, sc))
            no_pid_sc = set(raw_pts) ^ set(sync_pts)
            for ps in no_pid_sc:
                pid = ps.split('_')[0]
                type_id = ps.split('_')[1]
                sc = ps.split('_')[2]
                models.FakeTgt.objects.create(pid=pid, type_id=type_id, sc=sc)
        return super(BaseTargetAdmin, self).get_queryset(request)

    def delete_queryset(self, request, queryset):
        os = queryset.values()
        for obj in os:
            project_id = obj['project_id']
            serial_number = obj['serial_number']
            models.FakeTgt.objects.filter(pid=project_id, sc=serial_number).delete()
        super(BaseTargetAdmin, self).delete_queryset(request, queryset)


@admin.register(models.SettingsThreshold)
class SettingsThresholdAdmin(ImportExportModelAdmin):
    """阈值信息"""
    resource_class = resource.SettingsThresholdResource
    list_display = ('id', 'target', 'quota', 'level', 'lower', 'upper', 'absolute')
    list_editable = ('target', 'quota', 'level', 'lower', 'upper', 'absolute')
    fields = ('target', 'quota', 'level', 'lower', 'upper', 'absolute')
    list_display_links = ('id',)
    empty_value_display = '-auto-'
    ordering = ('id',)
    raw_id_fields = ('target', 'quota')
    search_fields = ['target__id']
    readonly_fields = ['id']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        # 判断有效性【每个等级的最大值大于最小值】
        if float(obj.lower) > float(obj.upper):
            msg = '【阈值下限】必须小于【阈值上限】'
            err_msg(request, msg)
        obj.quota_code = models.SettingsDataQuota.objects.get(id=obj.quota_id).code
        obj.name = obj.level.name
        set_user(request, obj)
        super(SettingsThresholdAdmin, self).save_model(request, obj, form, change)


@admin.register(models.PyDBHandle)
class PyDBHandleAdmin(admin.ModelAdmin):
    """数据删除记录"""
    list_display = ('id', 'target', 'start_time', 'end_time', 'status', 'progress', 'handle', 'create_user_id',
                    'create_time', 'remarks')
    list_editable = ('target', 'start_time', 'end_time', 'remarks')
    fields = ('target', 'start_time', 'end_time', 'remarks')
    ordering = ('id',)
    raw_id_fields = ('target',)
    empty_value_display = '-auto-'
    search_fields = ['target__id', 'create_time', 'remarks']
    list_per_page = 20

    def has_delete_permission(self, request, obj=None):
        return True

    def save_model(self, request, obj, form, change):
        if obj.start_time is not None and obj.end_time is not None and obj.start_time >= obj.end_time:
            msg = '结束时间【end_time】必须晚于开始时间【start_time】'
            err_msg(request, msg)
        if obj.remarks is None:
            obj.remarks = '如果有数值范围条件限制，可以为该记录添加【删除条件】'
        set_user(request, obj)
        super(PyDBHandleAdmin, self).save_model(request, obj, form, change)


@admin.register(models.PyDBCondition)
class PyDBConditionAdmin(admin.ModelAdmin):
    """数据删除条件"""
    list_display = ('id', 'handle', 'quota', 'lower', 'upper', 'and_or', 'remarks')
    list_editable = ('handle', 'quota', 'lower', 'upper', 'and_or', 'remarks')
    fields = ('handle', 'quota', 'lower', 'upper', 'and_or', 'remarks')
    ordering = ('id',)
    raw_id_fields = ('handle', 'quota',)
    empty_value_display = '-auto-'
    search_fields = ['handle__id', 'quota__id']
    list_per_page = 20

    def save_model(self, request, obj, form, change):
        tid = models.PyDBHandle.objects.get(id=obj.handle_id).target_id
        type_id = models.BaseTarget.objects.get(id=tid).type_id
        type_name = models.BaseTargetType.objects.get(id=type_id).name
        quotas = models.SettingsDataQuota.objects.filter(target_type_id=type_id).values()
        qid = []
        for q in quotas:
            qid.append(q['id'])
        if obj.quota_id not in qid:
            msg = '指标id【{}】选择有误！记录中的测点【{}】是【{}】类型，该类型包含的指标id有{}'.format(obj.quota_id, tid, type_name, qid)
            err_msg(request, msg)
        elif obj.lower is None and obj.upper is None:
            msg = '【阈值下限】和【阈值上限】不能都为空'
            err_msg(request, msg)
        else:
            if obj.remarks is None:
                obj.remarks = '运算关系：当存在多个删除条件时，这个条件和其他条件的逻辑运算关系'
        set_user(request, obj)
        super(PyDBConditionAdmin, self).save_model(request, obj, form, change)


@admin.register(models.FakeEnv)
class FakeEvnAdmin(admin.ModelAdmin):
    """模拟环境信息"""
    list_display = ('id', 'env', 'is_enable', 'host', 'port', 'vhost', 'username', 'password', 'exchange',
                    'routing_key', 'remarks')
    list_editable = ('exchange', 'remarks')
    fields = ('id', 'env', 'is_enable', 'host', 'port', 'vhost', 'username', 'password', 'exchange', 'routing_key',
              'remarks', 'update_user_id', 'update_time')
    readonly_fields = ['id', 'env', 'is_enable', 'update_user_id', 'update_time']
    ordering = ('id',)
    list_display_links = ('id', 'host', 'port', 'vhost', 'username', 'password', 'routing_key')
    list_per_page = 20

    # 增加自定义按钮
    actions = ['custom_button']

    def custom_button(self, request, queryset):
        pass

    custom_button.short_description = ' 返回数据模拟'
    custom_button.icon = 'fas fa-backward'
    custom_button.type = 'info'
    custom_button.style = 'font-size: 10px;'
    custom_button.action_type = 0
    custom_button.action_url = '/chart/fake/'

    def has_delete_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return True

    def save_model(self, request, obj, form, change):
        env = int(cache.get('env'))
        if obj.env != env:
            models.FakeEnv.objects.update(is_enable=0)
            models.FakeEnv.objects.filter(env=env).update(is_enable=1)
        set_user(request, obj)
        super(FakeEvnAdmin, self).save_model(request, obj, form, change)
        RabbitUtil.init(models.FakeEnv.objects.get(is_enable=1))

    def get_queryset(self, request):
        obj = models.FakeEnv.objects.filter(is_enable=1).values()
        env = int(cache.get('env'))
        if len(obj) == 0 or obj[0]['env'] != env:
            models.FakeEnv.objects.update(is_enable=0)
            models.FakeEnv.objects.filter(env=env).update(is_enable=1)
        qs = super(FakeEvnAdmin, self).get_queryset(request)
        return qs.filter(env=env)


@admin.register(models.FakeVal)
class FakeValAdmin(admin.ModelAdmin):
    """模拟环境信息"""
    list_display = ('type_id', 'type_code', 'type_name', 'is_enable', 'min_val', 'max_val', 'interval', 'decimal',
                    'remarks')
    list_editable = ('is_enable', 'min_val', 'max_val', 'interval', 'decimal', 'remarks')
    fields = ('type_id', 'type_code', 'type_name', 'is_enable', 'min_val', 'max_val', 'interval', 'decimal', 'remarks',
              'update_user_id', 'update_time')
    readonly_fields = ['type_id', 'type_code', 'type_name', 'update_user_id', 'update_time']
    ordering = ('type_id',)
    list_filter = ('type_id', 'type_code', 'type_name', 'is_enable')
    list_per_page = 20

    # 增加自定义按钮
    actions = ['back_button', 'fc_enable_button', 'fc_disable_button']

    def back_button(self, request, queryset):
        pass

    def fc_enable_button(self, request, queryset):
        models.FakeVal.objects.update(is_enable=1)

    def fc_disable_button(self, request, queryset):
        models.FakeVal.objects.update(is_enable=0)

    def changelist_view(self, request, extra_context=None):
        if 'action' in request.POST and request.POST['action'].startswith('fc_'):
            if not request.POST.getlist(ACTION_CHECKBOX_NAME):
                post = request.POST.copy()
                for u in models.FakeVal.objects.all():
                    post.update({ACTION_CHECKBOX_NAME: str(u.id)})
                request.POST = post
        return super(FakeValAdmin, self).changelist_view(request, extra_context)

    # 按钮名称
    back_button.short_description = ' 返回数据模拟'
    fc_enable_button.short_description = ' 全部启用'
    fc_disable_button.short_description = ' 全部停用'

    # 按钮图标
    back_button.icon = 'fas fa-backward'
    fc_enable_button.icon = 'fas fa-lock-open'
    fc_disable_button.icon = 'fas fa-lock'

    # 按钮颜色
    back_button.type = 'info'
    fc_enable_button.type = 'success'
    fc_disable_button.type = 'danger'

    back_button.action_type = 0
    back_button.action_url = '/chart/fake/'

    def has_delete_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return True


@admin.register(models.FakeTgt)
class FakeTgtAdmin(admin.ModelAdmin):
    """模拟环境信息"""
    list_display = ('id', 'pid', 'type_id', 'sc', 'is_enable')
    list_editable = ('is_enable',)
    list_filter = ('pid', 'type_id', 'is_enable')
    fields = ('id', 'pid', 'type_id', 'sc', 'is_enable')
    readonly_fields = ['id', 'pid', 'type_id', 'sc']
    list_per_page = 20

    # 增加自定义按钮
    actions = ['back_button', 'fc_enable_button', 'fc_disable_button']

    def back_button(self, request, queryset):
        pass

    def fc_enable_button(self, request, queryset):
        models.FakeTgt.objects.update(is_enable=1)

    def fc_disable_button(self, request, queryset):
        models.FakeTgt.objects.update(is_enable=0)

    def changelist_view(self, request, extra_context=None):
        if 'action' in request.POST and request.POST['action'].startswith('fc_'):
            if not request.POST.getlist(ACTION_CHECKBOX_NAME):
                post = request.POST.copy()
                for u in models.FakeVal.objects.all():
                    post.update({ACTION_CHECKBOX_NAME: str(u.id)})
                request.POST = post
        return super(FakeTgtAdmin, self).changelist_view(request, extra_context)

    # 按钮名称
    back_button.short_description = ' 返回数据模拟'
    fc_enable_button.short_description = ' 全部启用'
    fc_disable_button.short_description = ' 全部停用'

    # 按钮图标
    back_button.icon = 'fas fa-backward'
    fc_enable_button.icon = 'fas fa-lock-open'
    fc_disable_button.icon = 'fas fa-lock'

    # 按钮颜色
    back_button.type = 'info'
    fc_enable_button.type = 'success'
    fc_disable_button.type = 'danger'

    back_button.action_type = 0
    back_button.action_url = '/chart/fake/'

    def has_delete_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return True


@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
    """日志信息"""
    list_display = ('action_time', 'user', 'action_flag', 'content_type', 'object_id', 'change_message')
    fields = ('user', 'action_flag', 'content_type', 'object_id', 'change_message')
    search_fields = ['action_time', 'user__username']
    list_per_page = 20

    def has_delete_permission(self, request, obj=None):
        return False

    def has_add_permission(self, request):
        return False

    def has_change_permission(self, request, obj=None):
        return False


# 定制admin页面显示(在其中一个admin中配置下就行了)
admin.site.site_header = '云庐PMS'
admin.site.site_title = '云庐PMS'
admin.site.index_title = '测点信息管理系统'

# 不显示认证和授权
# admin.site.unregister(Group)
# admin.site.unregister(User)
